/***************************************************************************
 *   Copyright (C) 2008/2009 by Philipp Müller                             *
 *   philipp.mueller@gmx.de                                                *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA          *
 ***************************************************************************/

#include <QtCore>
#include <QtGui>
#include <QtNetwork>

#include "qtvomp.h"
#include "mediawidgetitem.h"
#include "vompglobal.h"
#include "enterchannelnumber.h"
#include "dlgrecordinginformation.h"

MainWindow::MainWindow( QHostAddress server, QWidget *parent ) : QMainWindow( parent )
{
    qDebug() << "MainWindow::MainWindow called";

    //Connect and login to VDR
    m_vdrThread.moveToThread( &m_vdrThread );
    m_vdrThread.start();

    if ( server.isNull() ) //no server yet specified
    {
        server = searchForServer( &m_vdrThread );
    }

    if ( server.isNull() ) //still no server found, abborting
    {
        exit( 1 );
    }

    m_vdr = m_vdrThread.vdr();
    m_vdr->setVDRServerAddress( server );

    m_serverTimeOffset = m_vdr->requestLogin();

    m_settings = new Settings( this );
    m_settings->loadSettings();

    //Start initatlising the objects
    m_mediaList = 0L;

    m_centralWidget = new QStackedWidget( this );
    setCentralWidget( m_centralWidget );

    m_channelListModel = new ChannelListModel( this, this );
    m_channelListSelectionModel = new QItemSelectionModel( m_channelListModel );

    m_timerListModel = new TimerListModel( this, this );
    m_timerListSelectionModel = new QItemSelectionModel( m_timerListModel );

    m_timer = new QTimer( this );

    m_menuWidget          = new QWidget( m_centralWidget );
    m_channelListWidget   = new WidgetChannelList( this, m_centralWidget );
    m_widgetPlayVideo     = new WidgetPlayVideo( this, m_centralWidget );
    m_recordingsWidget    = new QWidget( m_centralWidget );
    m_mediaWidget         = new QWidget( m_centralWidget );
    m_epgWidget           = new WidgetEpg( this, m_centralWidget );
    m_timersWidget        = new WidgetTimers( this, m_centralWidget );
    m_optionsWidget       = new WidgetOptions( this, m_centralWidget );

    initMenuWidget();
    m_centralWidget->insertWidget( WIDGET_MENU, m_menuWidget );

    initChannelListWidget();
    m_centralWidget->insertWidget( WIDGET_CHANNELS, m_channelListWidget );

    initRecordingsWidget();
    m_centralWidget->insertWidget( WIDGET_RECORDINGS, m_recordingsWidget );

    initTimersWidget();
    m_centralWidget->insertWidget( WIDGET_TIMERS, m_timersWidget );

    initMediaWidget();
    m_centralWidget->insertWidget( WIDGET_MEDIA, m_mediaWidget );

    initEpgWidget();
    m_centralWidget->insertWidget( WIDGET_EPG, m_epgWidget );

    initOptionsWidget();
    m_centralWidget->insertWidget( WIDGET_OPTIONS, m_optionsWidget );

    m_widgetPlayVideo->initWidgetPlayVideo();
    m_centralWidget->insertWidget( WIDGET_PLAYVIDEO, m_widgetPlayVideo );

    displayMenu();

    setWindowTitle( tr( "Qt for VOMP" ) );

    qRegisterMetaType< TimerEntry >( "TimerEntry" );
    qRegisterMetaType< QHostAddress >( "QHostAddress" );
    qRegisterMetaType< ChannelList >( "ChannelList" );
    qRegisterMetaType< ScheduleList >( "ScheduleList" );
    qRegisterMetaType< QList<RecordingsEntry> >( "QList<RecordingsEntry>" );
    qRegisterMetaType< QList<TimerEntry> >( "QList<TimerEntry>" );
    qRegisterMetaType< QList<MediaEntry> >( "QList<MediaEntry>" );

    //TV Channellist
    connect( this,  SIGNAL( getChannelList( quint32 ) ),
             m_vdr, SLOT( getChannelList( quint32 ) ) );
    connect( m_vdr, SIGNAL( channelListAvailable( const ChannelList & ) ),
             this,  SLOT( updateChannels( const ChannelList & ) ) );

    //TV Schedules
    connect( m_channelListModel, SIGNAL( getSchedule( quint32 ) ),
             m_vdr,              SLOT( getSchedule( quint32 ) ) );
    connect( m_channelListModel, SIGNAL( getSchedule( quint32 , QDateTime, quint32 ) ),
             m_vdr,              SLOT( getSchedule( quint32 , QDateTime, quint32 ) ) );
    connect( m_vdr,              SIGNAL( scheduleAvailable( quint32, const ScheduleList & ) ),
             m_channelListModel, SLOT( updateSchedule( quint32, const ScheduleList & ) ) );

    //Recordingslist
    connect( this,  SIGNAL( getRecordingsList() ),
             m_vdr, SLOT( getRecordingsList() ) );
    connect( m_vdr, SIGNAL( recordingsAvailable( const QList<RecordingsEntry> & ) ),
             this,  SLOT( updateRecordings( const QList<RecordingsEntry> & ) ) );

    //Timerlist
    connect( this,  SIGNAL( getTimerList() ),
             m_vdr, SLOT( getTimerList() ) );
    connect( m_vdr, SIGNAL( timersAvailable( const QList<TimerEntry> & ) ),
             this,  SLOT( updateTimers( const QList<TimerEntry> & ) ) );

    //Check set timer result
    connect( m_vdr, SIGNAL( timerSet( int ) ),
             this,  SLOT( checkSetTimerResult( int ) ) );

    //Check delete timer result
    connect( m_vdr, SIGNAL( timerDeleted( int ) ),
             this,  SLOT( checkDeleteTimerResult( int ) ) );

    //Check edit timer result
    connect( m_vdr, SIGNAL( timerChanged( int ) ),
             this,  SLOT( checkEditTimerResult( int ) ) );

    //Medialist
    connect( this,  SIGNAL( requestMediaList( const QString& ) ),
             m_vdr, SLOT( requestMediaList( const QString& ) ) );
    connect( m_vdr, SIGNAL( mediaListAvailable( const QList<MediaEntry> & ) ),
             this,  SLOT( updateMediaList( const QList<MediaEntry> & ) ) );

    //Osd update channel info
    connect( m_channelListModel,       SIGNAL( dataChanged( const QModelIndex &, const QModelIndex & ) ),
             m_widgetPlayVideo->osd(), SLOT( updateOsdTv( const QModelIndex &, const QModelIndex & ) ) );

    qDebug() << "MainWindow::MainWindow done";
}


MainWindow::~MainWindow()
{
    delete m_settings;
}


void MainWindow::closeEvent ( QCloseEvent * event )
{
    qDebug() << "MainWindow::closeEvent called";
    if ( m_widgetPlayVideo->mediaObject()->state() == Phonon::PlayingState ||
         m_widgetPlayVideo->mediaObject()->state() == Phonon::BufferingState )
    {
        m_widgetPlayVideo->stopPlayVideo();

        hide();

        //Restart the close event and give Phonon some time to react
        QTimer::singleShot( 100, this, SLOT( close() ) );

        event->ignore();
        return;
    }

    //Delete this first, otherwise Xine crashes on close
    delete m_widgetPlayVideo;

    event->accept();

    qDebug() << "MainWindow::closeEvent ended";
}


QHostAddress MainWindow::searchForServer( VDRThread * thread )
{
    QHostAddress server;

    /* Broadcast for servers */
    VDRFindServer* find = thread->vdrFindServer();
    if ( !find->socketEstablished() )
    {
        qWarning() << "Binding to socket 3024 failed. Maybe you have a VDR instance running on this machine.";
        int ret = QMessageBox::warning( this,
                                        tr("QtVomp"),
                                        tr("Couldn't bind to socket 3024.\n\nMaybe your are running QtVomp on a machine with a VDR instance?\nIf not, please start QtVomp with the -s <ip-address> command line argument.\n\nIs VDR running on this machine?" ),
                                        QMessageBox::Yes | QMessageBox::No );
        if ( ret == QMessageBox::Yes )
        {
            return QHostAddress( "127.0.0.1" );
        }
        else
        {
            bool ok;
            QString ipEntered = QInputDialog::getText(this,
                                                      tr("IP Address of VDR server"),
                                                      tr("Enter the IP Address of the server:"),
                                                      QLineEdit::Normal,
                                                      "127.0.0.1",
                                                      &ok);
            if ( ok && !ipEntered.isEmpty() )
            {
                ok = server.setAddress( ipEntered );
                if ( ok )
                {
                    return server;
                }
                else
                {
                    return QHostAddress();
                }
            }

            return QHostAddress();
        }
    }

    bool serverFound = false;
    int loops = 0;

    while ( !serverFound && loops < 10 )
    {
        QList<serverEntry> serverList = find->serverList();

        if ( serverList.count() == 1 )
        {
            serverFound = true;
            server = serverList[0].hostAddress;
        }
        else
            if ( serverList.count() > 1 )
            {
                serverFound = true;

                QDialog* dlg = new QDialog();
                QVBoxLayout *vbox = new QVBoxLayout;
                QButtonGroup *buttonGroup = new QButtonGroup( dlg );

                QGroupBox *groupBox = new QGroupBox( "Select a server" );
                groupBox->setFlat( true );

                QPushButton* button;

                for ( int i = 0; i < serverList.size(); ++i )
                {
                    button = new QPushButton( serverList[i].hostName, dlg );
                    buttonGroup->addButton( button, i );
                    vbox->addWidget( button );
                }

                dlg->connect( buttonGroup, SIGNAL( buttonClicked( int ) ), dlg, SLOT( done( int ) ) );

                vbox->addStretch( 1 );
                groupBox->setLayout( vbox );

                QVBoxLayout *vbox2 = new QVBoxLayout;
                vbox2->addWidget( groupBox );

                dlg->setLayout( vbox2 );
                int result = dlg->exec();
                server = serverList[result].hostAddress;

                delete vbox;
                delete vbox2;
                delete dlg;
            }
    }

    return server;
}


void MainWindow::keyPressEvent( QKeyEvent * event )
{
    if( m_centralWidget->currentIndex() != WIDGET_CHANNELS )
    {
        return;
    }

    switch ( event->key() )
    {

        case Qt::Key_0:
        case Qt::Key_1:
        case Qt::Key_2:
        case Qt::Key_3:
        case Qt::Key_4:
        case Qt::Key_5:
        case Qt::Key_6:
        case Qt::Key_7:
        case Qt::Key_8:
        case Qt::Key_9:
        {
            EnterChannelNumber *channel = new EnterChannelNumber( event->text(), this, this );
            channel->exec();
            delete channel;

            event->accept();

            return;
        }
    }
}


void MainWindow::moveEvent( QMoveEvent * event )
{
//     qDebug() << "MainWindow::moveEvent called";
    if( m_widgetPlayVideo && !m_widgetPlayVideo->isHidden() )
    {
        m_widgetPlayVideo->osd()->centerWidget();
    }
    QWidget::moveEvent( event );
}


void MainWindow::resizeEvent( QResizeEvent * event )
{
//     qDebug() << "MainWindow::resizeEvent called";
    if( m_widgetPlayVideo && !m_widgetPlayVideo->isHidden() )
    {
        m_widgetPlayVideo->osd()->centerWidget();
    }
    QWidget::resizeEvent( event );
}


void MainWindow::hideEvent( QHideEvent * event )
{
//     qDebug() << "MainWindow::hideEvent called";
    if( m_widgetPlayVideo && !m_widgetPlayVideo->isHidden() )
    {
        m_widgetPlayVideo->osd()->hide();
    }
    QWidget::hideEvent( event );
}


void MainWindow::showEvent( QShowEvent * event )
{
//     qDebug() << "MainWindow::showEvent called";
    if( m_widgetPlayVideo && !m_widgetPlayVideo->isHidden() )
    {
        m_widgetPlayVideo->osd()->show();
    }
    QWidget::showEvent( event );
}


void MainWindow::displayMenu()
{
    m_centralWidget->setCurrentIndex( WIDGET_MENU );
}


void MainWindow::displayMenuTime()
{
    m_menuTimeLabel->setText( serverTime().toString( "hh:mm" ) );
}


void MainWindow::displayChannelList( bool loadChannels )
{
    qDebug() << "MainWindow::displayChannelList: was called";

    if ( loadChannels )
    {
        qDebug() << "MainWindow::displayChannelList: load channels";
        m_channelListModel->removeRows( 0, m_channelListModel->rowCount() );

        emit getChannelList( VDR::VIDEO );
    }
    m_centralWidget->setCurrentIndex( WIDGET_CHANNELS );

    m_channelListWidget->setFocusOnChannelList();

    qDebug() << "MainWindow:displayChannelList done";
}


void MainWindow::displayRecordings( bool loadRecordings )
{
    qDebug() << "MainWindow::displayRecordings: was called";

    if ( loadRecordings )
    {
        qDebug() << "MainWindow::displayRecordings: load recordings";
        m_recordingsList->clear();
        emit getRecordingsList();
    }

    m_centralWidget->setCurrentIndex( WIDGET_RECORDINGS );
}


void MainWindow::displayChannelsRadio( bool loadChannels )
{
    qDebug() << "MainWindow::displayChannelsRadio: was called";

    if ( loadChannels )
    {
        qDebug() << "MainWindow::displayChannelsRadio: load channels";
        m_channelListModel->removeRows( 0, m_channelListModel->rowCount() );

        emit getChannelList( VDR::RADIO );
    }

    m_centralWidget->setCurrentIndex( WIDGET_CHANNELS );

    qDebug() << "MainWindow:displayChannelsRadio done";
}


void MainWindow::displayOptions()
{
    m_optionsWidget->loadOptions();
    m_centralWidget->setCurrentIndex( WIDGET_OPTIONS );
}


void MainWindow::displayMediaList( bool loadMedia )
{
    if ( loadMedia )
    {
        displayMediaList(( QTreeWidgetItem* )0L );
    }
    else
    {
        m_centralWidget->setCurrentIndex( WIDGET_MEDIA );
    }
}


void MainWindow::displayMediaList( QTreeWidgetItem * item )
{
    if ( item == 0L )
    {
        //No Item selected, we clear the widget content
        m_mediaList->clear();
    }
    else
    {
        //expanded, we select the item
        m_mediaList->setCurrentItem( item );
    }

    m_centralWidget->setCurrentIndex( WIDGET_MEDIA );

    m_mediaListItem = static_cast<MediaWidgetItem*>( item );
    QString currentDir;

    if ( item != 0L )
    {
        //An item is selected, we want to refill this node again
        currentDir = m_mediaListItem->path() + '/';
        QList<QTreeWidgetItem *> list = item->takeChildren();
        list.clear();
        qDebug() << "CurrentDir for child entries: " << currentDir;
    }
    else
    {
        currentDir = "";
    }

    emit requestMediaList( currentDir );
}


void MainWindow::displayTimers()
{
    qDebug() << "MainWindow::displayTimers called";
    emit getTimerList();

    m_timersWidget->initScreen();

    m_centralWidget->setCurrentIndex( WIDGET_TIMERS );
}


void MainWindow::displayEpg()
{
    m_centralWidget->setCurrentIndex( WIDGET_EPG );

    m_epgWidget->initScreen();
}


void MainWindow::displayRecordingInformation()
{
    RecordingsWidgetItem* recordingItem = static_cast<RecordingsWidgetItem*>( recordingsList()->currentItem() );
    int type = recordingItem->entryType();

    if ( type != REC_TYPE_FILE )
    {
        qDebug() << "DlgRecordingInformation::DlgRecordingInformation entry is not a file -> return";
        return;
    }

    DlgRecordingInformation dlg( this, this );
    dlg.exec();
}


void MainWindow::updateChannels( const ChannelList & channelsList )
{
    qDebug() << "MainWindow:updateChannelsTV: size = " << channelsList.size();

    m_channelListModel->removeRows( 0, m_channelListModel->rowCount() );

    for ( int i = 0; i < channelsList.size(); ++i )
    {
        m_channelListModel->insertRow( i );
        if ( i > channelList()->count() - 1 || i < 0 )
        {
            qWarning() << "MainWindow::updateChannels::setChannelName: row is out of range";
            return;
        }
        m_channelList[ i ] = channelsList[ i ];

//         m_channelListModel->setChannelData( channelsList[i], i );
    }

    m_channelListSelectionModel->setCurrentIndex( m_channelListModel->index( 0, 0 ),
                                                  QItemSelectionModel::SelectCurrent |
                                                  QItemSelectionModel::Rows );
}


void MainWindow::updateRecordings( const QList<RecordingsEntry> & recordingsList )
{
    qDebug() << "MainWindow:updateRecordings: size = " << recordingsList.size();

    RecordingsWidgetItem *recordingsRootEntry;
    recordingsRootEntry = new RecordingsWidgetItem( m_recordingsList,
            QStringList( QStringList() <<
                         "Recordings" <<
                         "" ) );
    recordingsRootEntry->setExpanded( true );

    for ( int i = 0; i < recordingsList.size(); ++i )
    {
        addRecordingsWidgetItem( recordingsList[i].name, recordingsList[i].fileName, 0,
                                 recordingsList[i].start, recordingsRootEntry );
    }

    m_recordingsList->resizeColumnToContents( 0 );

    m_recordingsList->setCurrentItem( recordingsRootEntry );
}


void MainWindow::updateTimers( const QList<TimerEntry> & timerList )
{
    qDebug() << "MainWindow:updateTimers: size = " << timerList.size();
    m_timerList = timerList;

    m_timerListModel->removeRows( 0, m_timerListModel->rowCount() );

    for ( int i = 0; i < timerList.size(); ++i )
    {
        m_timerListModel->insertRow( i );
        m_timerListModel->setTimerData( timerList[ i ], i );
    }

    if ( timerList.size() > 0 )
    {
        m_timersWidget->timerListView()->setCurrentIndex( m_timersWidget->timerListView()->model()->index( 0, 0 ) );
    }
}


void MainWindow::checkSetTimerResult( int result )
{
    switch ( result )
    {

        case 0:
        {
            //ok, so reload the timerlist as it was changed
            emit getTimerList();
            return;
        }

        case 1:
        {
            QMessageBox::warning( this,
                                  tr("Could not set timer"),
                                  tr("There is already a timer for this event" ),
                                  QMessageBox::Ok );
            return;
        }

        case 2:
        {
            QMessageBox::critical( this,
                                   tr("Could not set timer"),
                                   tr("Failure setting timer" ),
                                   QMessageBox::Ok );
            return;
        }

        default:
        {
            qWarning() << "MainWindow::checkSetTimerResult unknown result code";
        }
    }
}


void MainWindow::checkDeleteTimerResult( int result )
{
    switch ( result )
    {

        case 10:
        {
            //ok, so reload the timerlist as it was changed
            emit getTimerList();
            return;
        }

        case 1:
        {
            QMessageBox::warning( this,
                                  tr("Could not delete timer"),
                                  tr("Timers being edited at VDR, please try later" ),
                                  QMessageBox::Ok );
            return;
        }

        case 3:
        {
            QMessageBox::warning( this,
                                  tr("Could not delete timer"),
                                  tr("Unable to delete timer - timer is running" ),
                                  QMessageBox::Ok );
            return;
        }

        case 4:
        {
            QMessageBox::critical( this,
                                   tr("Could not delete timer"),
                                   tr("Error - timer not found at VDR" ),
                                   QMessageBox::Ok );
            return;
        }

        default:
        {
            qWarning() << "MainWindow::checkDeleteTimerResult unknown result code";
        }
    }
}


void MainWindow::checkEditTimerResult( int result )
{
    qDebug() << "MainWindow::checkEditTimerResult result = " << result;
    switch ( result )
    {
        //The results of the deletion of old timer are sent as negative value
        case -10:
        {
            //ok, nothing to be done yet
            return;
        }

        case -1:
        {
            QMessageBox::warning( this,
                                  tr("Could not delete timer before changing it."),
                                  tr("Timers being edited at VDR, please try later" ),
                                  QMessageBox::Ok );
            return;
        }

        case -3:
        {
            QMessageBox::warning( this,
                                  tr("Could not delete timer before changing it"),
                                  tr("Unable to delete timer - timer is running" ),
                                  QMessageBox::Ok );
            return;
        }

        case -4:
        {
            QMessageBox::critical( this,
                                   tr("Could not delete timer before changing it"),
                                   tr("Error - timer not found at VDR" ),
                                   QMessageBox::Ok );
            return;
        }

        //The results of the setting of new timer are sent as positive value
        case 0:
        {
            //ok, so reload the timerlist as it was changed
            emit getTimerList();
            return;
        }

        case 1: //Should not happen
        {
            qWarning() << "MainWindow::checkDeleteTimerResult: Old timer was not deleted before new was set";
            QMessageBox::warning( this,
                                  tr("Could not set new timer"),
                                  tr("The timer was not changed for unknown reasons" ),
                                  QMessageBox::Ok );
            return;
        }

        case 2:
        {
            QMessageBox::critical( this,
                                   tr("Could not set timer"),
                                   tr("Failure setting new timer, original was most propabely deleted" ),
                                   QMessageBox::Ok );
            return;
        }

        default:
        {
            qWarning() << "MainWindow::checkDeleteTimerResult unknown result code";
        }
    }
}


void MainWindow::addRecordingsWidgetItem( const QString & text, const QString & fileName,
        int start, QDateTime dateTime, RecordingsWidgetItem * parentItem )
{
    bool found;
    int dirMarker = text.indexOf( "~", start );
    RecordingsWidgetItem *recordingsEntry;

    if ( dirMarker != -1 ) //We have a dir
    {
        //Search if dir already exists
        found = false;

        for ( int i = 0; i < parentItem->childCount(); i++ )
        {
            RecordingsWidgetItem * childItem = static_cast<RecordingsWidgetItem*>( parentItem->child( i ) );

            if ( childItem->entryName() == text.mid( start, dirMarker - start ) )
            {
                //We found it, so let's get to the next level
                addRecordingsWidgetItem( text, fileName, dirMarker + 1, dateTime, childItem );
                found = true;
            }
        }

        if ( !found )
        {
            recordingsEntry = new RecordingsWidgetItem( parentItem,
                    QStringList( QStringList() <<
                                 text.mid( start, dirMarker - start ) <<
                                 "" ) );
            recordingsEntry->setEntryName( text.mid( start, dirMarker - start ) );
            recordingsEntry->setPath( "" );
            recordingsEntry->setEntryType( REC_TYPE_DIR );
            recordingsEntry->setIcon( 0, QIcon( ":/images/folder.png" ) );

            addRecordingsWidgetItem( text, fileName, dirMarker + 1, dateTime, recordingsEntry );
        }
    }
    else
    {
        recordingsEntry = new RecordingsWidgetItem( parentItem,
                             QStringList( QStringList() <<
                             text.right( text.length() - start ) <<
                             dateTime.toString( "dd/MM hh:mm" ) ) );
        recordingsEntry->setEntryName( text.right( text.length() - start ) );
        recordingsEntry->setPath( fileName );
        recordingsEntry->setStart( dateTime );
        recordingsEntry->setEntryType( REC_TYPE_FILE );
        recordingsEntry->setIcon( 0, QIcon( ":/images/video.png" ) );
    }
}


void MainWindow::updateMediaList( const QList<MediaEntry> & mediaList )
{
    qDebug() << "MainWindow: updateMediaList";
    QTreeWidgetItem* currentItem = m_mediaList->currentItem();

    for ( int i = 0; i < mediaList.size(); ++i )
    {
        qDebug() << "MainWindow: updateMediaList entryName = " << mediaList[i].name;

        if ( m_mediaListItem != 0L )
        {
            m_mediaListItem->setChildIndicatorPolicy( QTreeWidgetItem::DontShowIndicatorWhenChildless );
        }

        MediaWidgetItem *mediaEntry;

        if ( m_mediaListItem == 0L )
        {
            //we need to populate the list first with the root dir entries
            mediaEntry = new MediaWidgetItem( m_mediaList,
                                              QStringList( QStringList() <<
                                                           mediaList[i].name <<
                                                           mediaList[i].time.toString( "dd/MM/yy hh:mm" ) ) );
        }
        else
        {
            // we need to bring children to a node
            mediaEntry = new MediaWidgetItem( m_mediaListItem,
                                              QStringList( QStringList() <<
                                                           mediaList[i].name <<
                                                           mediaList[i].time.toString( "dd/MM/yy hh:mm" ) ) );
        }

        mediaEntry->setPath( mediaList[i].name );

        mediaEntry->setEntryType( mediaList[i].type );
        mediaEntry->setDateTime( mediaList[i].time );

        switch ( mediaList[i].type )
        {

            case MEDIA_TYPE_DIR:
                mediaEntry->setIcon( 0, QIcon( ":/images/folder.png" ) );
                mediaEntry->setText( 1, "" ); //remove the text again
                break;

            case MEDIA_TYPE_AUDIO:
                mediaEntry->setIcon( 0, QIcon( ":/images/sound.png" ) );
                break;

            case MEDIA_TYPE_VIDEO:
                mediaEntry->setIcon( 0, QIcon( ":/images/video.png" ) );
                break;

            case MEDIA_TYPE_PICTURE:
                mediaEntry->setIcon( 0, QIcon( ":/images/image.png" ) );
                break;
        }

        if ( mediaList[i].type == MEDIA_TYPE_DIR ) //Default is show the indicator
            mediaEntry->setChildIndicatorPolicy( QTreeWidgetItem::ShowIndicator );
    }

    m_mediaList->resizeColumnToContents( 0 );

    if ( currentItem == 0L )
    {
        m_mediaList->setCurrentItem( m_mediaList->itemAt( 0, 0 ) );
    }
}


QDateTime MainWindow::serverTime()
{
    QDateTime time = QDateTime::currentDateTime();
    time = time.addSecs( m_serverTimeOffset );

    return time;
}


void MainWindow::initMenuWidget()
{
    //Layout spacers left and top

    QHBoxLayout* hBox;
    QVBoxLayout* vBox1;
    QVBoxLayout* vBox2;
    QSpacerItem* hSpacer1;
    QSpacerItem* hSpacer2;
    QSpacerItem* hSpacer3;
    QSpacerItem* vSpacer1;
    QSpacerItem* vSpacer2;

    hBox = new QHBoxLayout( m_menuWidget );
    hBox->setObjectName( QString::fromUtf8( "horizontalLayout" ) );
    hSpacer1 = new QSpacerItem( 40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum );
    hBox->addItem( hSpacer1 );

    vBox1 = new QVBoxLayout();
    vBox1->setObjectName( QString::fromUtf8( "verticalLayoutAll" ) );
    vSpacer1 = new QSpacerItem( 20, 40, QSizePolicy::Minimum, QSizePolicy::Expanding );

    vBox1->addItem( vSpacer1 );

    vBox2 = new QVBoxLayout();
    vBox2->setObjectName( QString::fromUtf8( "verticalLayoutButtonGroup" ) );

    //----Widgets

    QButtonGroup* menuButtons = new QButtonGroup( m_menuWidget );

    QPushButton* menuTV = new QPushButton( tr( "Live TV" ), this );
    vBox2->addWidget( menuTV );
    menuButtons->addButton( menuTV, 0 );
    connect( menuTV, SIGNAL( clicked() ), this, SLOT( displayChannelList() ) );

    QPushButton* menuRadio = new QPushButton( tr( "Radio" ), m_menuWidget );
    vBox2->addWidget( menuRadio );
    menuButtons->addButton( menuRadio, 1 );
    connect( menuRadio, SIGNAL( clicked() ), this, SLOT( displayChannelsRadio() ));

    QPushButton* menuRecordings = new QPushButton( tr( "Recordings" ), m_menuWidget );
    vBox2->addWidget( menuRecordings );
    menuButtons->addButton( menuRecordings, 2 );
    connect( menuRecordings, SIGNAL( clicked() ), this, SLOT( displayRecordings() ) );

    QPushButton* menuTimers = new QPushButton( tr( "Timers" ), m_menuWidget );
    vBox2->addWidget( menuTimers );
    menuButtons->addButton( menuTimers, 3 );
    connect( menuTimers, SIGNAL( clicked() ), this, SLOT( displayTimers() ) );

    QPushButton* menuMediaPlayer = new QPushButton( tr( "Media player" ), m_menuWidget );
    vBox2->addWidget( menuMediaPlayer );
    menuButtons->addButton( menuMediaPlayer, 4 );
    connect( menuMediaPlayer, SIGNAL( clicked() ), this, SLOT( displayMediaList() ) );

    QPushButton* menuOptions = new QPushButton( tr( "Options" ), m_menuWidget );
    vBox2->addWidget( menuOptions );
    menuButtons->addButton( menuOptions, 6 );
    connect( menuOptions, SIGNAL( clicked() ), this, SLOT( displayOptions() ) );

    QTime time = QTime::currentTime();
    QString text = time.toString( "hh:mm" );

    m_menuTimeLabel = new QLabel( text, m_menuWidget );
    vBox2->addWidget( m_menuTimeLabel, 1, Qt::AlignRight );

    connect( m_timer, SIGNAL( timeout() ), this, SLOT( displayMenuTime() ) );
    m_timer->start( 1000 );


    //Layout spacers bottom and right

    hSpacer3 = new QSpacerItem( 40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum );
    vBox2->addItem( hSpacer3 );

    vBox1->addLayout( vBox2 );
    hBox->addLayout( vBox1 );

    vSpacer2 = new QSpacerItem( 20, 40, QSizePolicy::Minimum, QSizePolicy::Expanding );
    vBox1->addItem( vSpacer2 );

    hSpacer2 = new QSpacerItem( 40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum );
    hBox->addItem( hSpacer2 );
}


void MainWindow::initChannelListWidget()
{
//     qDebug() << "MainWindow::initChannelsTVWidget called";

    connect( m_channelListWidget, SIGNAL( playTV() ),
             m_widgetPlayVideo,   SLOT( playTV() ) );
}


void MainWindow::initRecordingsWidget()
{
    QVBoxLayout* vBox;
    QHBoxLayout* hBox;

    vBox = new QVBoxLayout( m_recordingsWidget );
    vBox->setObjectName( QString::fromUtf8( "verticalLayout" ) );

    //Recording list
    m_recordingsList = new QTreeWidget( m_recordingsWidget );
    m_recordingsList->setColumnCount( 2 );
    m_recordingsList->setHeaderLabels( QStringList() << "Recording" << "Date" );
    m_recordingsList->setSortingEnabled( true );
    m_recordingsList->setIconSize( QSize( 22, 22 ) );

    vBox->addWidget( m_recordingsList );

    //Button bar
    hBox = new QHBoxLayout();
    hBox->setObjectName( QString::fromUtf8( "horizontalLayout" ) );

    QPushButton* playButton = new QPushButton( tr( "Play" ), m_recordingsWidget );
    playButton->setIcon( style()->standardIcon( QStyle::SP_MediaPlay ) );
    hBox->addWidget( playButton );
    connect( playButton, SIGNAL( clicked() ), m_widgetPlayVideo, SLOT( playRecording() ) );

    QPushButton* infoButton = new QPushButton( tr( "Information" ), m_recordingsWidget );
    infoButton->setIcon( style()->standardIcon( QStyle::SP_MessageBoxInformation ) );
    hBox->addWidget( infoButton );
    connect( infoButton, SIGNAL( clicked() ), this, SLOT( displayRecordingInformation() ) );

    hBox->addStretch();

    QPushButton* backButton = new QPushButton( tr( "Back" ), m_recordingsWidget );
    backButton->setIcon( style()->standardIcon( QStyle::SP_ArrowLeft ) );
    hBox->addWidget( backButton );
    connect( backButton, SIGNAL( clicked() ), this, SLOT( displayMenu() ) );

    vBox->addLayout( hBox );
}


void MainWindow::initMediaWidget()
{
    QVBoxLayout* vBox;
    QHBoxLayout* hBox;

    vBox = new QVBoxLayout( m_mediaWidget );
    vBox->setObjectName( QString::fromUtf8( "verticalLayout" ) );

    //Medialist
    m_mediaList = new QTreeWidget( m_mediaWidget );
    m_mediaList->setColumnCount( 2 );
    m_mediaList->setHeaderLabels( QStringList() << "File" << "Date" );
    m_mediaList->setSortingEnabled( true );
    m_mediaList->setIconSize( QSize( 22, 22 ) );

    connect( m_mediaList, SIGNAL( itemExpanded( QTreeWidgetItem * ) ),
             this,        SLOT( displayMediaList( QTreeWidgetItem * ) ) );

    connect( m_mediaList,       SIGNAL( itemDoubleClicked( QTreeWidgetItem *, int ) ),
             m_widgetPlayVideo, SLOT( playMedia() ) );

    vBox->addWidget( m_mediaList );

    //Button bar
    hBox = new QHBoxLayout();
    hBox->setObjectName( QString::fromUtf8( "horizontalLayout" ) );

    QPushButton* playButton = new QPushButton( tr( "Play" ), m_mediaWidget );
    playButton->setIcon( style()->standardIcon( QStyle::SP_MediaPlay ) );
    hBox->addWidget( playButton );
    connect( playButton, SIGNAL( clicked() ), m_widgetPlayVideo, SLOT( playMedia() ) );

    hBox->addStretch();

    QPushButton* backButton = new QPushButton( tr( "Back" ), m_mediaWidget );
    backButton->setIcon( style()->standardIcon( QStyle::SP_ArrowLeft ) );
    hBox->addWidget( backButton );
    connect( backButton, SIGNAL( clicked() ), this, SLOT( displayMenu() ) );

    vBox->addLayout( hBox );
}


void MainWindow::initOptionsWidget()
{
    connect( m_optionsWidget, SIGNAL( back() ), this, SLOT( displayMenu() ) );
}


void MainWindow::initEpgWidget()
{
}


void MainWindow::initTimersWidget()
{
    connect( m_timersWidget, SIGNAL( back() ), this, SLOT( displayMenu() ) );
}
